<script setup lang="ts">
import { getDicomSource } from '@/config/config'
import {
  Enums,
  RenderingEngine,
  Types,
  volumeLoader,
  utilities, setVolumesForViewports
} from '@cornerstonejs/core'
import * as cornerstone from '@cornerstonejs/core'
import { adaptersSEG } from '@cornerstonejs/adapters'
import { metaData } from '@cornerstonejs/core'
import { api } from 'dicomweb-client'
import { onMounted, ref } from 'vue'
import * as cornerstoneTools from '@cornerstonejs/tools'
import { initDemo, createImageIdsAndCacheMetaData } from '@/helpers'
import { StackScrollMouseWheelTool, ToolGroupManager, SegmentationDisplayTool } from '@cornerstonejs/tools'

const idPrefix = 'load-segment-stack'
const uuid = utilities.uuidv4()

const { ViewportType } = Enums
let renderingEngineId = `${idPrefix}-renderingEngineId-${uuid}`
let volumeId = `${idPrefix}-volumeId-${uuid}`
const viewportId = `${idPrefix}-viewportId-${uuid}`
const segmentationId = 'segmentation-image-volume:' + uuid
const stackToolGroupId = `${idPrefix}-stackToolGroupId-${uuid}`
const volumeToolGroupId = `${idPrefix}-volumeToolGroupId-${uuid}`

let renderingEngine
let imageIds
let volume
let volumeToolGroup
let stackToolGroup
const renderContainerRef = ref(null)

const {
  segmentation,
  Enums: csToolsEnums
} = cornerstoneTools

async function getImageIds() {
  const params = {
    StudyInstanceUID: '1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046',
    SeriesInstanceUID: '1.3.12.2.1107.5.2.32.35162.1999123112191238897317963.0.0.0',
    wadoRsRoot: `https://d33do7qe4w26qo.cloudfront.net/dicomweb`
  }
  imageIds = await createImageIdsAndCacheMetaData(params)
}

async function addSegmentationsToState() {
  const segParams = {
    studyInstanceUID: '1.3.12.2.1107.5.2.32.35162.30000015050317233592200000046',
    seriesInstanceUID: '1.2.276.0.7230010.3.1.3.296485376.8.1542816659.201008',
    sopInstanceUID: '1.2.276.0.7230010.3.1.4.296485376.8.1542816659.201009',
    wadoRsRoot: 'https://d33do7qe4w26qo.cloudfront.net/dicomweb'
  }
  const arrayBuffer = await retrieveDicomData(segParams)
  const result = await adaptersSEG.Cornerstone3D.Segmentation.generateToolState(imageIds, arrayBuffer, metaData)
  const segmentationVolume = await volumeLoader.createAndCacheDerivedSegmentationVolume(volumeId, {
    volumeId: segmentationId
  })
  segmentation.addSegmentations([
    {
      segmentationId: segmentationId,
      representation: {
        // The type of segmentation
        type: csToolsEnums.SegmentationRepresentations.Labelmap,
        // The actual segmentation data, in the case of labelmap this is a
        // reference to the source volume of the segmentation.
        data: {
          volumeId: segmentationId
        }
      }
    }
  ])
  const segmentationVolume1 = cornerstone.cache.getVolume(segmentationVolume.volumeId)
  const scalarData = segmentationVolume1.getScalarData()
  scalarData.set(new Uint8Array(result.labelmapBufferArray[0]))
}

function retrieveDicomData({ studyInstanceUID, seriesInstanceUID, sopInstanceUID, wadoRsRoot }) {
  const client = new api.DICOMwebClient({
    url: wadoRsRoot
  })
  const options = {
    studyInstanceUID,
    seriesInstanceUID,
    sopInstanceUID
  }
  return client.retrieveInstance(options)
}

const initTools = () => {
  volumeToolGroup = ToolGroupManager.createToolGroup(volumeToolGroupId)
  stackToolGroup = ToolGroupManager.createToolGroup(stackToolGroupId);

  [stackToolGroup, volumeToolGroup].forEach((toolGroup) => {
    // Add the tools to the tool group
    toolGroup.addTool(StackScrollMouseWheelTool.toolName)

    toolGroup.addTool(SegmentationDisplayTool.toolName)


    toolGroup.setToolActive(StackScrollMouseWheelTool.toolName)
    toolGroup.setToolEnabled(SegmentationDisplayTool.toolName)
  })
}

const initRender = async () => {
  renderingEngine = new RenderingEngine(renderingEngineId)
  const viewportInputArray = [{
    viewportId,
    type: ViewportType.ORTHOGRAPHIC,
    element: renderContainerRef.value,
    defaultOptions: {
      orientation: Enums.OrientationAxis.SAGITTAL,
      background: <Types.Point3>[0.2, 0, 0.2]
    }
  }]
  renderingEngine.setViewports(viewportInputArray)
  volumeToolGroup.addViewport(viewportId, renderingEngineId)
  volume.load()
  await setVolumesForViewports(
    renderingEngine,
    [{ volumeId }],
    [viewportId]
  )
  await segmentation.addSegmentationRepresentations(volumeToolGroupId, [
    {
      segmentationId,
      type: csToolsEnums.SegmentationRepresentations.Labelmap
    }
  ])
}

async function createVolume() {
  volume = await volumeLoader.createAndCacheVolume(volumeId, {
    imageIds
  })
}

async function convert2Stack() {
  const viewport = renderingEngine.getViewport(viewportId)
  let newViewport
  segmentation.state.removeSegmentationRepresentations(stackToolGroupId)
  newViewport = await utilities.convertVolumeToStackViewport({
    viewport: viewport as Types.IVolumeViewport,
    options: {
      background: <Types.Point3>[0.4, 0, 0.4]
    }
  })
  await segmentation.convertVolumeToStackSegmentation({
    segmentationId,
    options: {
      toolGroupId: stackToolGroupId
    }
  })
  if (stackToolGroup) {
    stackToolGroup.addViewport(newViewport.id, renderingEngineId)
  }
}

onMounted(async () => {
  await initDemo()
  initTools()
  await getImageIds()
  await createVolume()
  await addSegmentationsToState()
  await initRender()
  // setTimeout(async () => {
  //   await convert2Stack()
  // }, 500)
})

</script>

<template>
  <div class="w-full h-[500px] bg-transparent flex justify-center">
    <div class="w-[600px] h-full bg-transparent  relative" ref="renderContainerRef">
    </div>
  </div>
</template>

<style scoped>

</style>
